package com.aspectj.core;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import com.aspectj.anno.After;
import com.aspectj.anno.AfterReturning;
import com.aspectj.anno.AfterThrowing;
import com.aspectj.anno.Around;
import com.aspectj.anno.Aspect;
import com.aspectj.anno.Before;
import com.aspectj.anno.Pointcut;
import com.aspectj.param.AspectBean;
import com.aspectj.param.AspectType;

/**
 * 方法1：这种方法无法注入aspect
 * 
 * @author Administrator
 *
 */
@Component
public class AopBeanPostProcessor implements BeanPostProcessor {
	Map<AspectType, AspectBean> aspectBeansMap = new HashMap<>();
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		Class<?> targetClass = bean.getClass();
		if (targetClass.isAnnotationPresent(Aspect.class)) {
			Method[] methods = targetClass.getDeclaredMethods();
			for (Method method : methods) {
				Annotation[] annos = method.getAnnotations();
				if(annos!=null&&annos.length>0) {
					Annotation anno = annos[0];
					if (anno instanceof Pointcut) {
						aspectBeansMap.put(AspectType.POINTCUT, new AspectBean(bean,method, anno));
					}
					if (anno instanceof Before) {
						aspectBeansMap.put(AspectType.BEFORE, new AspectBean(bean,method, anno));
					}
					if (anno instanceof After) {
						aspectBeansMap.put(AspectType.AFTER, new AspectBean(bean,method, anno));
					}
					if (anno instanceof AfterReturning) {
						aspectBeansMap.put(AspectType.AFTER_RETURNING, new AspectBean(bean,method, anno));
					}
					if (anno instanceof AfterThrowing) {
						aspectBeansMap.put(AspectType.AFTER_THROWING, new AspectBean(bean,method, anno));
					}
					if (anno instanceof Around) {
						aspectBeansMap.put(AspectType.AROUND, new AspectBean(bean,method, anno));
					}
				}
			}
		}
		Object proxy = AopProxy.newProxyInstance(bean, aspectBeansMap);
		return proxy;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
	}
}
